<?php


namespace kernel;


class Load
{
    /** @var ArgvData */
    public static $argvObj;

    public static function run()
    {
        static::$argvObj = new ArgvData();
        // 没有传入方法时，则提示能执行的方法
        if (empty(static::$argvObj->action)
            || strpos(static::$argvObj->action, '-') === 0) {
            return static::showAction();
        }
        return static::execute();
    }

    public static function execute()
    {
        $argvObj = static::$argvObj;
        // 执行方法
        $errMsg = '无可执行的方法：' . $argvObj->action;
        if (!empty($argvObj->action)) {
            $action = ['dsp'];
            $action = array_merge($action, explode('/', $argvObj->action));
            list($action[2], $action[3]) = ['main', $action[2]];
            $len = count($action);
            $action[$len - 2] = ucfirst($action[$len - 2]);
            // 将下划线转驼峰
            if (strpos($action[$len - 1], '-') !== false) {
                $action[$len - 1] = Tools::camelize($action[$len - 1], '-');
            }

            $methodName = $action[$len - 1];
            unset($action[$len - 1]);
            $className = implode('\\', $action);
            $errMsg = '找不到该执行的方法' . $argvObj->action . ':' . __LINE__ . PHP_EOL;
            if (class_exists($className)) {
                $class = new \ReflectionClass($className);
                // 不能实例化抽象类 或 接口类
                if (!$class->isAbstract() || !$class->isInterface()) {
                    $errMsg = '找不到该执行的方法：' . $argvObj->action . ':' . __LINE__ . PHP_EOL;
                    if ($class->hasMethod($methodName)) {
                        $classObj = $class->newInstanceArgs();
                        $method = new \ReflectionMethod($classObj, $methodName);
                        if ($method->isPublic() && !$method->isStatic()) {
                            return $method->invokeArgs($classObj, $argvObj->param);
                        }
                    }
                }
            }
        }
        exit($errMsg);
    }

    public static function showAction()
    {
        echo PHP_EOL . '==========  以下是可执行的方法 ==========' . PHP_EOL . PHP_EOL;
        $path = ROOT . '/src';
        $dirs = scandir($path);
        foreach ($dirs as $dir) {
            if ($dir != '.' && $dir != '..') {
                $fileName = $path . '/' . $dir . '/Main.php';
                $className = 'dsp\\' . $dir . '\\Main';
                if (file_exists($fileName) && class_exists($className)) {
                    $class = new \ReflectionClass($className);
                    $methods = $class->getMethods();
                    /** only execute public method */
                    foreach ($methods as $method) {
                        if ($method->isPublic()) {
                            $methodName = Tools::uncamelize($method->getName(), '-');
                            $commandName = $dir . '/' . $methodName;
                            echo '-> ' . $commandName . PHP_EOL;
                        }
                    }
                    echo PHP_EOL;
                }
            }
        }
        echo PHP_EOL;
    }

}